package schedulo.gui.components;

import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;

import javax.swing.JFormattedTextField;
import javax.swing.JSlider;
import javax.swing.JTextField;
import java.awt.Insets;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Observable;

import javax.swing.JToggleButton;
import javax.swing.JComboBox;

import schedulo.core.task.Task;
import schedulo.core.util.CalendarUtils;

public class NewTaskPanel extends JPanel {

	private LinkedList<NewTaskPanelListener> listeners;

	public void addNewTaskPanelListener(NewTaskPanelListener listener) {
		listeners.add(listener);
	}

	public void removeNewTaskPanelListener(NewTaskPanelListener listener) {
		listeners.remove(listener);
	}

	public static final String[] TASK_PRIORITIES = { "Urgent", "Important",
			"None" };

	private JLabel labelTaskStatus = null;

	private JLabel labelTaskLoadMinimal = null;

	private JLabel labelMaximalLoad = null;

	private JSlider sliderStatus = null;

	private JFormattedTextField textMinimalLoad = null;

	private JFormattedTextField textMaximalLoad = null;

	private JLabel jLabel = null;

	private JComboBox comboLoadUnit = null;

	private JLabel labelFromDate = null;

	private JFormattedTextField textFromDate = null;

	private JLabel labelDueDate = null;

	private JFormattedTextField textDueDate = null;

	private JLabel labelResources = null;

	private JTextField textResources = null;

	private JLabel labelDescription = null;

	private JTextField textDescription = null;

	private JLabel labelPriority = null;

	private JComboBox comboPriority = null;

	/**
	 * This method initializes
	 * 
	 */
	public NewTaskPanel() {
		super();
		listeners = new LinkedList<NewTaskPanelListener>();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
		GridBagConstraints gridBagConstraints101 = new GridBagConstraints();
		gridBagConstraints101.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints101.gridy = 0;
		gridBagConstraints101.weightx = 1.0;
		gridBagConstraints101.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints101.anchor = GridBagConstraints.WEST;
		gridBagConstraints101.gridx = 2;
		GridBagConstraints gridBagConstraints91 = new GridBagConstraints();
		gridBagConstraints91.gridx = 1;
		gridBagConstraints91.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints91.anchor = GridBagConstraints.WEST;
		gridBagConstraints91.gridy = 0;
		labelPriority = new JLabel();
		labelPriority.setText("Priority");
		GridBagConstraints gridBagConstraints81 = new GridBagConstraints();
		gridBagConstraints81.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints81.gridy = 5;
		gridBagConstraints81.weightx = 1.0;
		gridBagConstraints81.anchor = GridBagConstraints.WEST;
		gridBagConstraints81.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints81.gridwidth = 3;
		gridBagConstraints81.gridx = 2;
		GridBagConstraints gridBagConstraints71 = new GridBagConstraints();
		gridBagConstraints71.gridx = 1;
		gridBagConstraints71.anchor = GridBagConstraints.WEST;
		gridBagConstraints71.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints71.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints71.gridy = 5;
		labelDescription = new JLabel();
		labelDescription.setText("Description");
		GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
		gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints6.gridy = 4;
		gridBagConstraints6.weightx = 1.0;
		gridBagConstraints6.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints6.gridwidth = 3;
		gridBagConstraints6.gridx = 2;
		GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
		gridBagConstraints5.gridx = 1;
		gridBagConstraints5.anchor = GridBagConstraints.WEST;
		gridBagConstraints5.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints5.gridy = 4;
		labelResources = new JLabel();
		labelResources.setText("Resources");
		GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
		gridBagConstraints4.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints4.gridy = 3;
		gridBagConstraints4.weightx = 1.0;
		gridBagConstraints4.anchor = GridBagConstraints.WEST;
		gridBagConstraints4.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints4.gridx = 4;
		GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
		gridBagConstraints3.gridx = 3;
		gridBagConstraints3.insets = new Insets(5, 15, 5, 5);
		gridBagConstraints3.gridy = 3;
		labelDueDate = new JLabel();
		labelDueDate.setText("Due date");
		GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
		gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints2.gridy = 3;
		gridBagConstraints2.weightx = 1.0;
		gridBagConstraints2.anchor = GridBagConstraints.WEST;
		gridBagConstraints2.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints2.gridx = 2;
		GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
		gridBagConstraints1.gridx = 1;
		gridBagConstraints1.anchor = GridBagConstraints.NORTHWEST;
		gridBagConstraints1.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints1.gridy = 3;
		labelFromDate = new JLabel();
		labelFromDate.setText("From date");
		GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
		gridBagConstraints14.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints14.gridy = 1;
		gridBagConstraints14.weightx = 0.0D;
		gridBagConstraints14.anchor = GridBagConstraints.WEST;
		gridBagConstraints14.gridheight = 2;
		gridBagConstraints14.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints14.gridx = 4;
		GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
		gridBagConstraints13.gridx = 3;
		gridBagConstraints13.gridheight = 2;
		gridBagConstraints13.insets = new Insets(5, 15, 5, 5);
		gridBagConstraints13.anchor = GridBagConstraints.WEST;
		gridBagConstraints13.gridy = 1;
		jLabel = new JLabel();
		jLabel.setText("Load unit");
		GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
		gridBagConstraints11.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints11.gridy = 2;
		gridBagConstraints11.weightx = 0.0D;
		gridBagConstraints11.anchor = GridBagConstraints.NORTHWEST;
		gridBagConstraints11.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints11.gridx = 2;
		GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
		gridBagConstraints10.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints10.gridy = 1;
		gridBagConstraints10.weightx = 0.0D;
		gridBagConstraints10.anchor = GridBagConstraints.NORTHWEST;
		gridBagConstraints10.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints10.gridx = 2;
		GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
		gridBagConstraints9.fill = GridBagConstraints.BOTH;
		gridBagConstraints9.gridy = 0;
		gridBagConstraints9.weightx = 1.0D;
		gridBagConstraints9.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints9.anchor = GridBagConstraints.NORTHWEST;
		gridBagConstraints9.gridwidth = 1;
		gridBagConstraints9.weighty = 0.0D;
		gridBagConstraints9.gridx = 4;
		GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
		gridBagConstraints8.gridx = 1;
		gridBagConstraints8.anchor = GridBagConstraints.WEST;
		gridBagConstraints8.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints8.gridy = 2;
		labelMaximalLoad = new JLabel();
		labelMaximalLoad.setText("Maximal load");
		GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
		gridBagConstraints7.gridx = 1;
		gridBagConstraints7.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints7.anchor = GridBagConstraints.WEST;
		gridBagConstraints7.gridy = 1;
		labelTaskLoadMinimal = new JLabel();
		labelTaskLoadMinimal.setText("Minimal load");
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 3;
		gridBagConstraints.anchor = GridBagConstraints.WEST;
		gridBagConstraints.insets = new Insets(5, 15, 5, 5);
		gridBagConstraints.gridy = 0;
		labelTaskStatus = new JLabel();
		labelTaskStatus.setText("Status");
		this.setLayout(new GridBagLayout());
		this.setSize(new Dimension(323, 186));
		this.add(labelTaskStatus, gridBagConstraints);
		this.add(labelTaskLoadMinimal, gridBagConstraints7);
		this.add(labelMaximalLoad, gridBagConstraints8);
		this.add(getSliderStatus(), gridBagConstraints9);
		this.add(getTextMinimalLoad(), gridBagConstraints10);
		this.add(getTextMaximalLoad(), gridBagConstraints11);
		this.add(jLabel, gridBagConstraints13);
		this.add(getComboLoadUnit(), gridBagConstraints14);
		this.add(labelFromDate, gridBagConstraints1);
		this.add(getTextFromDate(), gridBagConstraints2);
		this.add(labelDueDate, gridBagConstraints3);
		this.add(getTextDueDate(), gridBagConstraints4);
		this.add(labelResources, gridBagConstraints5);
		this.add(getTextResources(), gridBagConstraints6);
		this.add(labelDescription, gridBagConstraints71);
		this.add(getTextDescription(), gridBagConstraints81);
		this.add(labelPriority, gridBagConstraints91);
		this.add(getComboPriority(), gridBagConstraints101);

	}

	/**
	 * This method initializes sliderStatus
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getSliderStatus() {
		if (sliderStatus == null) {
			sliderStatus = new JSlider();
			sliderStatus.setValue(0);
			sliderStatus.setPreferredSize(new Dimension(50, 16));
			sliderStatus
					.addChangeListener(new javax.swing.event.ChangeListener() {
						public void stateChanged(javax.swing.event.ChangeEvent e) {
							isValid();
						}
					});
		}
		return sliderStatus;
	}

	/**
	 * This method initializes textMinimalLoad
	 * 
	 * @return javax.swing.JTextField
	 */
	private JFormattedTextField getTextMinimalLoad() {
		if (textMinimalLoad == null) {
			textMinimalLoad = new JFormattedTextField(NumberFormat
					.getInstance());
			textMinimalLoad.setColumns(3);
			textMinimalLoad.addKeyListener(new java.awt.event.KeyAdapter() {
				public void keyTyped(java.awt.event.KeyEvent e) {
					isValid();
				}
			});
		}
		return textMinimalLoad;
	}

	/**
	 * This method initializes textMaximalLoad
	 * 
	 * @return javax.swing.JTextField
	 */
	private JFormattedTextField getTextMaximalLoad() {
		if (textMaximalLoad == null) {
			textMaximalLoad = new JFormattedTextField(NumberFormat
					.getInstance());
			textMaximalLoad.setColumns(3);
			textMaximalLoad.addKeyListener(new java.awt.event.KeyAdapter() {
				public void keyTyped(java.awt.event.KeyEvent e) {
					isValid();
				}
			});
		}
		return textMaximalLoad;
	}

	/**
	 * This method initializes comboLoadUnit
	 * 
	 * @return javax.swing.JComboBox
	 */
	private JComboBox getComboLoadUnit() {
		if (comboLoadUnit == null) {
			comboLoadUnit = new JComboBox(Task.LOAD_UNITS);
			comboLoadUnit.setSelectedItem(Task.LOAD_UNIT_DAY2);
			comboLoadUnit
					.addActionListener(new java.awt.event.ActionListener() {
						public void actionPerformed(java.awt.event.ActionEvent e) {
							isValid();
						}
					});
			comboLoadUnit.addItemListener(new java.awt.event.ItemListener() {
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					isValid();
				}
			});
		}
		return comboLoadUnit;
	}

	@Override
	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
		getSliderStatus().setEnabled(enabled);
		getTextMinimalLoad().setEnabled(enabled);
		getTextMaximalLoad().setEnabled(enabled);
		getComboLoadUnit().setEnabled(enabled);
		getTextFromDate().setEnabled(enabled);
		getTextDueDate().setEnabled(enabled);
		getTextDescription().setEnabled(enabled);
		getTextResources().setEnabled(enabled);

	}

	/**
	 * This method initializes textFromDate
	 * 
	 * @return javax.swing.JTextField
	 */
	private JFormattedTextField getTextFromDate() {
		if (textFromDate == null) {
			textFromDate = new JFormattedTextField(new SimpleDateFormat(
					"dd/MM/yyyy"));
			textFromDate.addKeyListener(new java.awt.event.KeyAdapter() {
				public void keyTyped(java.awt.event.KeyEvent e) {
					isValid();
				}
			});
		}
		return textFromDate;
	}

	/**
	 * This method initializes textDueDate
	 * 
	 * @return javax.swing.JTextField
	 */
	private JFormattedTextField getTextDueDate() {
		if (textDueDate == null) {
			textDueDate = new JFormattedTextField(new SimpleDateFormat(
					"dd/MM/yyyy"));
			textDueDate.addKeyListener(new java.awt.event.KeyAdapter() {
				public void keyTyped(java.awt.event.KeyEvent e) {
					isValid();
				}
			});
		}
		return textDueDate;
	}

	/**
	 * This method initializes textResources
	 * 
	 * @return javax.swing.JTextField
	 */
	private JTextField getTextResources() {
		if (textResources == null) {
			textResources = new JTextField();
			textResources.addKeyListener(new java.awt.event.KeyAdapter() {
				public void keyTyped(java.awt.event.KeyEvent e) {
					isValid();
				}
			});
		}
		return textResources;
	}

	/**
	 * This method initializes textDescription
	 * 
	 * @return javax.swing.JTextField
	 */
	private JTextField getTextDescription() {
		if (textDescription == null) {
			textDescription = new JTextField();
			textDescription.addKeyListener(new java.awt.event.KeyAdapter() {
				public void keyTyped(java.awt.event.KeyEvent e) {
					isValid();
				}
			});
		}
		return textDescription;
	}

	public boolean isValid() {
		// verify all fields
		// if(getTextFromDate().getV)
		if (getTextDescription().getText() == null
				|| getTextDescription().getText().trim().length() == 0) {
			fireNewTaskPanelNotification(false);
			return false;
		}

		try {
			getTextDueDate().commitEdit();
			if (getTextDueDate().getValue() == null) {
				fireNewTaskPanelNotification(false);
				return false;
			}
		} catch (ParseException e) {
			fireNewTaskPanelNotification(false);
			return false;
		}

		if (!isJFormattedTextFieldValid(getTextDueDate())) {
			fireNewTaskPanelNotification(false);
			return false;
		}

		if (!isJFormattedTextFieldValid(getTextFromDate())) {
			fireNewTaskPanelNotification(false);
			return false;
		}

		if (!isJFormattedTextFieldValid(getTextMaximalLoad())) {
			fireNewTaskPanelNotification(false);
			return false;
		}

		if (!isJFormattedTextFieldValid(getTextMinimalLoad())) {
			fireNewTaskPanelNotification(false);
			return false;
		}

		if (getTextResources().getText() != null
				&& !getTextResources().getText().matches(
						"\\s*\\w{3}(?:/\\s*\\w{3})*\\s*")) {
			fireNewTaskPanelNotification(false);
			return false;
		}

		fireNewTaskPanelNotification(true);
		return true;
	}

	private boolean isJFormattedTextFieldValid(JFormattedTextField tf) {
		try {
			tf.commitEdit();
			if (tf.getValue() == null) {
				return false;
			}
		} catch (ParseException e) {
			return false;
		}
		return true;
	}

	protected void fireNewTaskPanelNotification(boolean taskValid) {
		Iterator<NewTaskPanelListener> itL = listeners.iterator();
		while (itL.hasNext()) {
			itL.next().newTaskPanelNotification(taskValid);
		}
	}

	public Task getNewTask() {
		Task task = new Task();
		task.setDescription(getTextDescription().getText());
		task.setDueDate(CalendarUtils.getInstance((Date) getTextDueDate()
				.getValue()));
		task.setStartDate(CalendarUtils.getInstance((Date) getTextFromDate()
				.getValue()));
		task.setLoadMax(((Double) getTextMaximalLoad().getValue())
				.doubleValue());
		task.setLoadMin(((Double) getTextMinimalLoad().getValue())
				.doubleValue());
		task.setLoadUnit(getComboLoadUnit().getSelectedItem().toString());
		if (TASK_PRIORITIES[0].equals(getComboPriority().getSelectedItem())) {
			task.setPriority(Task.PRIORITY_URGENT);
		} else if (TASK_PRIORITIES[1].equals(getComboPriority()
				.getSelectedItem())) {
			task.setPriority(Task.PRIORITY_IMPORTANT);
		} else if (TASK_PRIORITIES[2].equals(getComboPriority()
				.getSelectedItem())) {
			task.setPriority(Task.PRIORITY_NORMAL);
		}
		task.setProgress((double) getSliderStatus().getValue() / 100);
		task.setResources(getTextResources().getText());
		return new Task();
	}

	/**
	 * This method initializes comboPriority
	 * 
	 * @return javax.swing.JComboBox
	 */
	private JComboBox getComboPriority() {
		if (comboPriority == null) {
			comboPriority = new JComboBox(TASK_PRIORITIES);
			comboPriority.setSelectedItem(TASK_PRIORITIES[2]);
		}
		return comboPriority;
	}

} // @jve:decl-index=0:visual-constraint="10,10"
